﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Liang.Util.Crypt.Dll
{
    /// <summary>
    /// CSP API
    /// </summary>
    class CryptAPI
    {
        /// <summary>
        /// <para>获取CSP服务</para>
        /// <para>C++函数原型：</para>
        /// <para>BOOL WINAPI CryptAcquireContext(_Out_ HCRYPTPROV *phProv, _In_ LPCTSTR pszContainer, _In_ LPCTSTR pszProvider, _In_ DWORD dwProvType, _In_ DWORD dwFlags)</para>
        /// </summary>
        /// <param name="phProv"></param>
        /// <param name="pszContainer"></param>
        /// <param name="pszProvider"></param>
        /// <param name="dwProvType"></param>
        /// <param name="dwFlags"></param>
        /// <returns></returns>
        [DllImport("Advapi32.dll")]
        public static extern Int32 CryptAcquireContext(ref IntPtr phProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);

        /// <summary>
        /// <para>创建哈希</para>
        /// <para>C++函数原型：</para>
        /// <para>BOOL WINAPI CryptCreateHash(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ HCRYPTKEY hKey, _In_ DWORD dwFlags, _Out_ HCRYPTHASH *phHash)</para>
        /// </summary>
        /// <param name="hProv"></param>
        /// <param name="Algid"></param>
        /// <param name="hKey"></param>
        /// <param name="dwFlags"></param>
        /// <param name="phHash"></param>
        /// <returns></returns>
        [DllImport("Advapi32.dll")]
        public static extern Int32 CryptCreateHash(UInt32 hProv, uint Algid, UInt32 hKey, uint dwFlags, ref IntPtr phHash);

        /// <summary>
        /// <para>哈希散列数据</para>
        /// <para>C++函数原型：</para>
        /// <para>BOOL WINAPI CryptHashData(_In_ HCRYPTHASH hHash, _In_ BYTE *pbData, _In_ DWORD dwDataLen, _In_ DWORD dwFlags)</para>
        /// </summary>
        /// <param name="hHash"></param>
        /// <param name="pbData"></param>
        /// <param name="dwDataLen"></param>
        /// <param name="dwFlags"></param>
        /// <returns></returns>
        [DllImport("Advapi32.dll")]
        public static extern Int32 CryptHashData(UInt32 hHash, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]byte[] pbData, uint dwDataLen, uint dwFlags);

        /// <summary>
        /// <para>派生密钥</para>
        /// <para>C++函数原型：</para>
        /// <para>BOOL WINAPI CryptDeriveKey(_In_ HCRYPTPROV hProv, _In_ ALG_ID Algid, _In_ HCRYPTHASH hBaseData, _In_ DWORD dwFlags, _Inout_ HCRYPTKEY *phKey)</para>
        /// </summary>
        /// <param name="hProv"></param>
        /// <param name="Algid"></param>
        /// <param name="hBaseData"></param>
        /// <param name="dwFlags"></param>
        /// <param name="phKey"></param>
        /// <returns></returns>
        [DllImport("Advapi32.dll")]
        public static extern Int32 CryptDeriveKey(UInt32 hProv, uint Algid, UInt32 hBaseData, uint dwFlags, ref IntPtr phKey);

        /// <summary>
        /// <para>加密数据</para>
        /// <para>C++函数原型：</para>
        /// <para>BOOL WINAPI CryptEncrypt(_In_ HCRYPTKEY hKey, _In_ HCRYPTHASH hHash, _In_ BOOL Final, _In_ DWORD dwFlags, _Inout_ BYTE *pbData, _Inout_ DWORD *pdwDataLen, _In_ DWORD dwBufLen)</para>
        /// </summary>
        /// <param name="hKey"></param>
        /// <param name="hHash"></param>
        /// <param name="bFinal"></param>
        /// <param name="dwFlags"></param>
        /// <param name="pbData"></param>
        /// <param name="pdwDataLen"></param>
        /// <param name="dwBufLen"></param>
        /// <returns></returns>
        [DllImport("Advapi32.dll")]
        public static extern Int32 CryptEncrypt(UInt32 hKey, UInt32 hHash, Int32 bFinal, uint dwFlags, IntPtr pbData, ref uint pdwDataLen, uint dwBufLen);

        /// <summary>
        /// <para>解密数据</para>
        /// <para>C++函数原型：</para>
        /// <para>BOOL WINAPI CryptDecrypt(_In_ HCRYPTKEY hKey,_In_ HCRYPTHASH hHash,_In_ BOOL Final,_In_ DWORD dwFlags, _Inout_ BYTE *pbData, _Inout_ DWORD *pdwDataLen)</para>
        /// </summary>
        /// <param name="hKey"></param>
        /// <param name="hHash"></param>
        /// <param name="bFinal"></param>
        /// <param name="dwFlags"></param>
        /// <param name="pbData"></param>
        /// <param name="pdwDataLen"></param>
        /// <returns></returns>
        [DllImport("Advapi32.dll")]
        public static extern Int32 CryptDecrypt(UInt32 hKey, UInt32 hHash, UInt32 bFinal, uint dwFlags, IntPtr pbData, ref uint pdwDataLen);

        /// <summary>
        /// <para>释放哈希函数句柄</para>
        /// <para>C++函数原型：</para>
        /// <para>BOOL WINAPI CryptDestroyHash(_In_ HCRYPTHASH hHash)</para>
        /// </summary>
        /// <param name="hHash"></param>
        /// <returns></returns>
        [DllImport("Advapi32.dll")]
        public static extern UInt32 CryptDestroyHash(UInt32 hHash);

        /// <summary>
        /// <para>释放密钥句柄</para>
        /// <para>C++函数原型：</para>
        /// <para>BOOL WINAPI CryptDestroyKey(_In_ HCRYPTKEY hKey)</para>
        /// </summary>
        /// <param name="hKey"></param>
        /// <returns></returns>
        [DllImport("Advapi32.dll")]
        public static extern UInt32 CryptDestroyKey(UInt32 hKey);

        /// <summary>
        /// <para>释放CSP资源</para>
        /// <para>C++函数原型：</para>
        /// <para>BOOL WINAPI CryptReleaseContext(_In_ HCRYPTPROV hProv, _In_ DWORD dwFlags)</para>
        /// </summary>
        /// <param name="hProv"></param>
        /// <param name="dwFlags"></param>
        /// <returns></returns>
        [DllImport("Advapi32.dll")]
        public static extern UInt32 CryptReleaseContext(uint hProv, uint dwFlags);


        /// <summary>
        /// 企业端司机卡交换数据解密函数
        /// <para>C++函数接口原型：</para>
        /// <para>typedef int (WINAPI *B64_DES)(LPSTR, LPSTR, LPSTR, ULONG, ULONG)</para>
        /// </summary>
        /// <param name="strIn">输入</param>
        /// <param name="strOut">输出</param>
        /// <param name="strKey">密钥</param>
        /// <param name="nBufSize">输入字符串长度</param>
        /// <param name="nFlag">0：解密  1：加密</param>
        /// <returns></returns>
        [DllImport("pbdes.dll")]
        public static extern int b64_des(string strIn,
            [MarshalAs(UnmanagedType.LPStr)]StringBuilder strOut, string strKey, uint nBufSize, uint nFlag);
    }
}